package com.example.onenet.activity;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.CoordinateConverter;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.example.onenet.R;
import com.example.onenet.model.GeoLocationItem;
import com.example.onenet.model.HumidityItem;
import com.example.onenet.model.OneNETStudioBase;
import com.example.onenet.model.TemperatureItem;
import com.example.onenet.model.WeightItem;
import com.example.onenet.utils.ToastUtil;
import com.example.onenet.utils.getOneNETDataUtil;
import com.github.cm.heclouds.onenet.studio.api.IotClient;
import com.github.cm.heclouds.onenet.studio.api.IotProfile;
import com.github.cm.heclouds.onenet.studio.api.auth.SignatureMethod;
import com.github.cm.heclouds.onenet.studio.api.entity.application.device.DeviceProperty;
import com.github.cm.heclouds.onenet.studio.api.entity.application.device.QueryDevicePropertyRequest;
import com.github.cm.heclouds.onenet.studio.api.exception.IotServerException;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.CountDownLatch;


public class MainActivity extends AppCompatActivity implements GeocodeSearch.OnGeocodeSearchListener {

    TextView tempTextView;
    TextView humiTextView;
    TextView weighTextView;
    TextView locationTextView;
    TextView addressTextView;
    TextView timeTextView;

    Button mapButton;

    private MapView mainMapView;
    private AMap aMap;

    private UiSettings mUiSettings;
    private GeocodeSearch geocoderSearch;
    private String addressName;

    ArrayList<OneNETStudioBase> devicePropertyList = new ArrayList<>();

    GeoLocationItem geoLocation;
    HumidityItem humidity = new HumidityItem();
    TemperatureItem temperature = new TemperatureItem();
    WeightItem weight = new WeightItem();
    private Date updateTime;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tempTextView = findViewById(R.id.tempTextView);
        humiTextView = findViewById(R.id.humiTextView);
        weighTextView = findViewById(R.id.weighTextView);
        locationTextView = findViewById(R.id.locationTextView);
        addressTextView = findViewById(R.id.addressTextView);
        timeTextView = findViewById(R.id.timeTextView);

        mapButton = findViewById(R.id.btn_map);
        mainMapView = findViewById(R.id.main_map);
        mainMapView.onCreate(savedInstanceState);// 此方法必须重写

        geocoderSearch = new GeocodeSearch(this);
        geocoderSearch.setOnGeocodeSearchListener(this);

        getOneNETDataUtil.createClient();
        networkThread.start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mymenu,menu);
        return true;
    }


    private final Handler mainHandle = new Handler(Looper.getMainLooper());
    private final Thread networkThread = new Thread() {
        @Override
        public void run() {
            super.run();
            while (true) {
                try {
                    Get();
                    Thread.sleep(3000); //每三秒get一次
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };

    @SuppressLint("SetTextI18n")
    public void Get() {

        getOneNETDataUtil.getDeviceProperty(devicePropertyList);

        for (OneNETStudioBase oneNETStudioBase :devicePropertyList){
            switch (oneNETStudioBase.getIdentifier()) {
                case "Temperature":
                    temperature.setTemperature(Double.parseDouble(oneNETStudioBase.getValue()));
                    updateTime = new Date(oneNETStudioBase.getTime());
                    break;
                case "Humidity":
                    humidity.setHumidity(Double.parseDouble(oneNETStudioBase.getValue()));
                    break;
                case "Weight":
                    weight.setWeight(Double.parseDouble(oneNETStudioBase.getValue()));
                    break;
                case "GeoLocation":
                    geoLocation = new Gson().fromJson(oneNETStudioBase.getValue().replace("\\", ""), GeoLocationItem.class);
                    break;
            }
        }

        mainHandle.post(() -> {
            //UI更新
            tempTextView.setText("温度:" + temperature.getTemperature()+"°C");
            humiTextView.setText("湿度:" + humidity.getHumidity()+"%");
            weighTextView.setText("重量:" + weight.getWeight());
            mapButton.setText("");
            locationTextView.setText("纬度:" + geoLocation.getLatitude() + "  经度:" + geoLocation.getLongitude());
            timeTextView.setText(updateTime.toString());
            mapInit(geoLocation.getLatitude(),geoLocation.getLongitude());
            getAddress(new LatLonPoint(geoLocation.getLatitude(),geoLocation.getLongitude()));
        });

    }


    /**
     * 初始化AMap对象
     */
    private void mapInit(double lat, double lon) {
        if (aMap == null) {
            aMap = mainMapView.getMap();
            mUiSettings = aMap.getUiSettings();
            mUiSettings.setZoomControlsEnabled(false);
        }
        LatLng latLng = converterCoord(lat,lon);
        //参数依次是：视角调整区域的中心点坐标、希望调整到的缩放级别、俯仰角0°~45°（垂直与地图时为0）、偏航角 0~360° (正北方为0)
        changeCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(latLng, 16, 30, 0)));
        final Marker marker = aMap.addMarker(new MarkerOptions().position(latLng)
                .icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
    }

    /**
     * 方法必须重写
     */
    public void openAMap(View view) {
        Intent intent = MapActivity.newIntent(MainActivity.this, geoLocation.getLatitude(), geoLocation.getLongitude());
        startActivity(intent);
    }

    public void onTest(View view) {
        openAMap(view);
    }

    /**
     * 根据动画按钮状态，调用函数animateCamera或moveCamera来改变可视区域
     */
    private void changeCamera(CameraUpdate update) {
        aMap.moveCamera(update);
    }

    private LatLng converterCoord(double lat, double lon) {
        LatLng sourceLatLng = new LatLng(lat, lon);
        CoordinateConverter converter = new CoordinateConverter(this);
        // CoordType.GPS 待转换坐标类型
        converter.from(CoordinateConverter.CoordType.GPS);
        // sourceLatLng待转换坐标点 LatLng类型
        converter.coord(sourceLatLng);
        return converter.convert();
    }

    public void getAddress(final LatLonPoint latLonPoint) {
        RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 100, GeocodeSearch.GPS);// 第一个参数表示一个Latlng，第二参数表示范围多少米，第三个参数表示是火系坐标系还是GPS原生坐标系
        geocoderSearch.getFromLocationAsyn(query);// 设置异步逆地理编码请求
    }


    @Override
    public void onGeocodeSearched(GeocodeResult result, int rCode) {

    }

    /**
     * 逆地理编码回调
     */
    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {

        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getRegeocodeAddress() != null
                    && result.getRegeocodeAddress().getFormatAddress() != null) {
                addressName = result.getRegeocodeAddress().getFormatAddress();
                addressTextView.setText(addressName);
            } else {
                ToastUtil.show(MainActivity.this, "NO SUCCESS");
            }
        } else {
            ToastUtil.showerror(this, rCode);
        }
    }

}